# -*- coding: utf-8 -*-
"""
Created on Fri Dec 05 10:40:11 2014

@author: Maxim
"""
import paths
import db_tools
import numpy as np

def load(name):
    mis = MissionProfile(name)
    return mis

class MissionProfile(object):
    """
    Loads data from mission.xls and stores in convinient way.
    if value is -1, then it should not be used. For example takeoff start speed 
    is 0 by default, so even if another value is inserted, it will be skipped 
    during calculation
    """
    def __init__(self,name):
        self._nonValue = -1
        self.name          = str(name)
        self.db = db_tools.ReadDatabase(paths.myPaths.db.mission,name)
        self.nMisSeg = self.db.nrows-1
        self._init_segments(self.nMisSeg)
        self._enter_values()
        self.calculated = False
        
    def _init_segments(self,nMisSeg):
        self.segmentName   = np.empty(nMisSeg,dtype='S10')
        self.altitudeStart = np.zeros(nMisSeg)
        self.altitudeEnd   = np.zeros(nMisSeg)
        self.airspeedStart = np.zeros(nMisSeg)
        self.airspeedEnd   = np.zeros(nMisSeg)
        #self.thrustSetting = np.zeros(nMisSeg)
        self.distance      = np.zeros(nMisSeg)
        self.time          = np.zeros(nMisSeg)
        self.nseg          = np.zeros(nMisSeg) # number of segments for integration
        # calculation result
        self.fuelBurned    = np.zeros(nMisSeg)
        self.fuelFraction  = np.zeros(nMisSeg)
        self.cumFuelFraction = np.zeros(nMisSeg)

    def _enter_values(self):
        def decompose(line):
            name = str(line[0])
            data = np.zeros(len(line)-1)
            for i,val in enumerate(line[1:]):
                if val=='':
                    data[i] = self._nonValue
                else:
                    data[i] = float(val)
            return name,data
        self.db._irowPrev = 0
        for i in range(self.nMisSeg):
            n,d = decompose(self.db.read_row(filterValues=False))
            self.segmentName[i]   = n
            self.altitudeStart[i] = d[0]
            self.altitudeEnd[i]   = d[1]
            self.airspeedStart[i] = d[2]
            self.airspeedEnd[i]   = d[3]
            #self.thrustSetting[i] = d[4]/100.
            self.distance[i]      = d[4]*1.0e3 #km -> m
            self.time[i]          = d[5]*3600. #h -> sec
            self.nseg[i]          = int(d[6])
    
    def __getitem__(self,idx):
        out = np.zeros(8)
        out[0] = self.altitudeStart[idx]
        out[1] = self.altitudeEnd[idx]
        out[2] = self.airspeedStart[idx]
        out[3] = self.airspeedEnd[idx]
        #out[4] = self.thrustSetting[idx]
        out[5] = self.distance[idx]
        out[6] = self.time[idx]
        out[7] = self.nseg[idx]
        return out
    
    def get_totals(self):
        self.totalRange = sum(self.distance)
        self.totalTime  = sum(self.time)
        self.totalFuelBurned = sum(self.fuelBurned)
    
    def _report(self):
        self.get_totals()
        out = '-'*61+'\n'
        out += '{:<12}{:>10}{:>10}{:>14}{:>14}\n'.format('Segment','Range, km','Time, hr', 'Fuel burned', 'Fuel fraction')
        out += '-'*61+'\n'
        for i in range(self.nMisSeg):
            seg = self.segmentName[i]
            R = self.distance[i]
            T = self.time[i]
            wf = self.fuelBurned[i]
            wff = self.fuelFraction[i]
            out += '{:<12}{:>10.1f}{:>10.2f}{:>14.2f}{:>14.2f}\n'.format(seg,R/1e3,T/3600,wf,wff)
        out += '-'*61+'\n'
        out += '{:<12}{:>10.1f}{:>10.2f}{:>14.2f}\n'.format('TOTAL',self.totalRange/1e3,self.totalTime/3600,self.totalFuelBurned)
        out += '-'*61+'\n'
        return out

    def __repr__(self):
        return self._report()
        

def run_test1():
    name = 'profile1'
    mis = load(name)
    print mis


if __name__=='__main__':
    run_test1()